package goqueryimport ()// After applies the selector from the root document and inserts the matched elements// after the elements in the set of matched elements.//// If one of the matched elements in the selection is not currently in the// document, it's impossible to insert nodes after it, so it will be ignored.//// This follows the same rules as Selection.Append.func ( *Selection) ( string) *Selection {return .AfterMatcher(compileMatcher())}// AfterMatcher applies the matcher from the root document and inserts the matched elements// after the elements in the set of matched elements.//// If one of the matched elements in the selection is not currently in the// document, it's impossible to insert nodes after it, so it will be ignored.//// This follows the same rules as Selection.Append.func ( *Selection) ( Matcher) *Selection {return .AfterNodes(.MatchAll(.document.rootNode)...)}// AfterSelection inserts the elements in the selection after each element in the set of matched// elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( *Selection) *Selection {return .AfterNodes(.Nodes...)}// AfterHtml parses the html and inserts it after the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( string) *Selection {return .eachNodeHtml(, true, func( *html.Node, []*html.Node) { := .NextSiblingfor , := range {if .Parent != nil { .Parent.InsertBefore(, ) } } })}// AfterNodes inserts the nodes after each element in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( ...*html.Node) *Selection {return .manipulateNodes(, true, func( *html.Node, *html.Node) {if .Parent != nil { .Parent.InsertBefore(, .NextSibling) } })}// Append appends the elements specified by the selector to the end of each element// in the set of matched elements, following those rules://// 1) The selector is applied to the root document.//// 2) Elements that are part of the document will be moved to the new location.//// 3) If there are multiple locations to append to, cloned nodes will be// appended to all target locations except the last one, which will be moved// as noted in (2).func ( *Selection) ( string) *Selection {return .AppendMatcher(compileMatcher())}// AppendMatcher appends the elements specified by the matcher to the end of each element// in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( Matcher) *Selection {return .AppendNodes(.MatchAll(.document.rootNode)...)}// AppendSelection appends the elements in the selection to the end of each element// in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( *Selection) *Selection {return .AppendNodes(.Nodes...)}// AppendHtml parses the html and appends it to the set of matched elements.func ( *Selection) ( string) *Selection {return .eachNodeHtml(, false, func( *html.Node, []*html.Node) {for , := range { .AppendChild() } })}// AppendNodes appends the specified nodes to each node in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( ...*html.Node) *Selection {return .manipulateNodes(, false, func( *html.Node, *html.Node) { .AppendChild() })}// Before inserts the matched elements before each element in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( string) *Selection {return .BeforeMatcher(compileMatcher())}// BeforeMatcher inserts the matched elements before each element in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( Matcher) *Selection {return .BeforeNodes(.MatchAll(.document.rootNode)...)}// BeforeSelection inserts the elements in the selection before each element in the set of matched// elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( *Selection) *Selection {return .BeforeNodes(.Nodes...)}// BeforeHtml parses the html and inserts it before the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( string) *Selection {return .eachNodeHtml(, true, func( *html.Node, []*html.Node) {for , := range {if .Parent != nil { .Parent.InsertBefore(, ) } } })}// BeforeNodes inserts the nodes before each element in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( ...*html.Node) *Selection {return .manipulateNodes(, false, func( *html.Node, *html.Node) {if .Parent != nil { .Parent.InsertBefore(, ) } })}// Clone creates a deep copy of the set of matched nodes. The new nodes will not be// attached to the document.func ( *Selection) () *Selection { := newEmptySelection(.document) .Nodes = cloneNodes(.Nodes)return}// Empty removes all children nodes from the set of matched elements.// It returns the children nodes in a new Selection.func ( *Selection) () *Selection {var []*html.Nodefor , := range .Nodes {for := .FirstChild; != nil; = .FirstChild { .RemoveChild() = append(, ) } }returnpushStack(, )}// Prepend prepends the elements specified by the selector to each element in// the set of matched elements, following the same rules as Append.func ( *Selection) ( string) *Selection {return .PrependMatcher(compileMatcher())}// PrependMatcher prepends the elements specified by the matcher to each// element in the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( Matcher) *Selection {return .PrependNodes(.MatchAll(.document.rootNode)...)}// PrependSelection prepends the elements in the selection to each element in// the set of matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( *Selection) *Selection {return .PrependNodes(.Nodes...)}// PrependHtml parses the html and prepends it to the set of matched elements.func ( *Selection) ( string) *Selection {return .eachNodeHtml(, false, func( *html.Node, []*html.Node) { := .FirstChildfor , := range { .InsertBefore(, ) } })}// PrependNodes prepends the specified nodes to each node in the set of// matched elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( ...*html.Node) *Selection {return .manipulateNodes(, true, func( *html.Node, *html.Node) {// sn.FirstChild may be nil, in which case this functions like // sn.AppendChild() .InsertBefore(, .FirstChild) })}// Remove removes the set of matched elements from the document.// It returns the same selection, now consisting of nodes not in the document.func ( *Selection) () *Selection {for , := range .Nodes {if .Parent != nil { .Parent.RemoveChild() } }return}// RemoveFiltered removes from the current set of matched elements those that// match the selector filter. It returns the Selection of removed nodes.//// For example if the selection s contains "<h1>", "<h2>" and "<h3>"// and s.RemoveFiltered("h2") is called, only the "<h2>" node is removed// (and returned), while "<h1>" and "<h3>" are kept in the document.func ( *Selection) ( string) *Selection {return .RemoveMatcher(compileMatcher())}// RemoveMatcher removes from the current set of matched elements those that// match the Matcher filter. It returns the Selection of removed nodes.// See RemoveFiltered for additional information.func ( *Selection) ( Matcher) *Selection {return .FilterMatcher().Remove()}// ReplaceWith replaces each element in the set of matched elements with the// nodes matched by the given selector.// It returns the removed elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( string) *Selection {return .ReplaceWithMatcher(compileMatcher())}// ReplaceWithMatcher replaces each element in the set of matched elements with// the nodes matched by the given Matcher.// It returns the removed elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( Matcher) *Selection {return .ReplaceWithNodes(.MatchAll(.document.rootNode)...)}// ReplaceWithSelection replaces each element in the set of matched elements with// the nodes from the given Selection.// It returns the removed elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( *Selection) *Selection {return .ReplaceWithNodes(.Nodes...)}// ReplaceWithHtml replaces each element in the set of matched elements with// the parsed HTML.// It returns the removed elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( string) *Selection { .eachNodeHtml(, true, func( *html.Node, []*html.Node) { := .NextSiblingfor , := range {if .Parent != nil { .Parent.InsertBefore(, ) } } })return .Remove()}// ReplaceWithNodes replaces each element in the set of matched elements with// the given nodes.// It returns the removed elements.//// This follows the same rules as Selection.Append.func ( *Selection) ( ...*html.Node) *Selection { .AfterNodes(...)return .Remove()}// SetHtml sets the html content of each element in the selection to// specified html string.func ( *Selection) ( string) *Selection {for , := range .Nodes {for := .FirstChild; != nil; = .FirstChild { .RemoveChild() } }return .eachNodeHtml(, false, func( *html.Node, []*html.Node) {for , := range { .AppendChild() } })}// SetText sets the content of each element in the selection to specified content.// The provided text string is escaped.func ( *Selection) ( string) *Selection {return .SetHtml(html.EscapeString())}// Unwrap removes the parents of the set of matched elements, leaving the matched// elements (and their siblings, if any) in their place.// It returns the original selection.func ( *Selection) () *Selection { .Parent().Each(func( int, *Selection) {// For some reason, jquery allows unwrap to remove the <head> element, so // allowing it here too. Same for <html>. Why it allows those elements to // be unwrapped while not allowing body is a mystery to me.if .Nodes[0].Data != "body" { .ReplaceWithSelection(.Contents()) } })return}// Wrap wraps each element in the set of matched elements inside the first// element matched by the given selector. The matched child is cloned before// being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( string) *Selection {return .WrapMatcher(compileMatcher())}// WrapMatcher wraps each element in the set of matched elements inside the// first element matched by the given matcher. The matched child is cloned// before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( Matcher) *Selection {return .wrapNodes(.MatchAll(.document.rootNode)...)}// WrapSelection wraps each element in the set of matched elements inside the// first element in the given Selection. The element is cloned before being// inserted into the document.//// It returns the original set of elements.func ( *Selection) ( *Selection) *Selection {return .wrapNodes(.Nodes...)}// WrapHtml wraps each element in the set of matched elements inside the inner-// most child of the given HTML.//// It returns the original set of elements.func ( *Selection) ( string) *Selection { := make(map[string][]*html.Node)for , := range .Nodes {var *html.Nodeif .Parent != nil { = .Parent } else { = &html.Node{Type: html.ElementNode} } , := [nodeName()]if ! { = parseHtmlWithContext(, ) [nodeName()] = }newSingleSelection(, .document).wrapAllNodes(cloneNodes()...) }return}// WrapNode wraps each element in the set of matched elements inside the inner-// most child of the given node. The given node is copied before being inserted// into the document.//// It returns the original set of elements.func ( *Selection) ( *html.Node) *Selection {return .wrapNodes()}func ( *Selection) ( ...*html.Node) *Selection { .Each(func( int, *Selection) { .wrapAllNodes(...) })return}// WrapAll wraps a single HTML structure, matched by the given selector, around// all elements in the set of matched elements. The matched child is cloned// before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( string) *Selection {return .WrapAllMatcher(compileMatcher())}// WrapAllMatcher wraps a single HTML structure, matched by the given Matcher,// around all elements in the set of matched elements. The matched child is// cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( Matcher) *Selection {return .wrapAllNodes(.MatchAll(.document.rootNode)...)}// WrapAllSelection wraps a single HTML structure, the first node of the given// Selection, around all elements in the set of matched elements. The matched// child is cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( *Selection) *Selection {return .wrapAllNodes(.Nodes...)}// WrapAllHtml wraps the given HTML structure around all elements in the set of// matched elements. The matched child is cloned before being inserted into the// document.//// It returns the original set of elements.func ( *Selection) ( string) *Selection {var *html.Nodevar []*html.Nodeiflen(.Nodes) > 0 { = .Nodes[0]if .Parent != nil { = parseHtmlWithContext(, ) } else { = parseHtml() } }return .wrapAllNodes(...)}func ( *Selection) ( ...*html.Node) *Selection {iflen() > 0 {return .WrapAllNode([0]) }return}// WrapAllNode wraps the given node around the first element in the Selection,// making all other nodes in the Selection children of the given node. The node// is cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( *html.Node) *Selection {if .Size() == 0 {return } := cloneNode() := .Nodes[0]if .Parent != nil { .Parent.InsertBefore(, ) .Parent.RemoveChild() }for := getFirstChildEl(); != nil; = getFirstChildEl() { = }newSingleSelection(, .document).AppendSelection()return}// WrapInner wraps an HTML structure, matched by the given selector, around the// content of element in the set of matched elements. The matched child is// cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( string) *Selection {return .WrapInnerMatcher(compileMatcher())}// WrapInnerMatcher wraps an HTML structure, matched by the given selector,// around the content of element in the set of matched elements. The matched// child is cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( Matcher) *Selection {return .wrapInnerNodes(.MatchAll(.document.rootNode)...)}// WrapInnerSelection wraps an HTML structure, matched by the given selector,// around the content of element in the set of matched elements. The matched// child is cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( *Selection) *Selection {return .wrapInnerNodes(.Nodes...)}// WrapInnerHtml wraps an HTML structure, matched by the given selector, around// the content of element in the set of matched elements. The matched child is// cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( string) *Selection { := make(map[string][]*html.Node)for , := range .Nodes { , := [nodeName()]if ! { = parseHtmlWithContext(, ) [nodeName()] = }newSingleSelection(, .document).wrapInnerNodes(cloneNodes()...) }return}// WrapInnerNode wraps an HTML structure, matched by the given selector, around// the content of element in the set of matched elements. The matched child is// cloned before being inserted into the document.//// It returns the original set of elements.func ( *Selection) ( *html.Node) *Selection {return .wrapInnerNodes()}func ( *Selection) ( ...*html.Node) *Selection {iflen() == 0 {return } .Each(func( int, *Selection) { := .Contents()if .Size() > 0 { .wrapAllNodes(...) } else { .AppendNodes(cloneNode([0])) } })return}func parseHtml( string) []*html.Node {// Errors are only returned when the io.Reader returns any error besides // EOF, but strings.Reader never will , := html.ParseFragment(strings.NewReader(), &html.Node{Type: html.ElementNode})if != nil {panic("goquery: failed to parse HTML: " + .Error()) }return}func parseHtmlWithContext( string, *html.Node) []*html.Node {// Errors are only returned when the io.Reader returns any error besides // EOF, but strings.Reader never will , := html.ParseFragment(strings.NewReader(), )if != nil {panic("goquery: failed to parse HTML: " + .Error()) }return}// Get the first child that is an ElementNodefunc getFirstChildEl( *html.Node) *html.Node { := .FirstChildfor != nil && .Type != html.ElementNode { = .NextSibling }return}// Deep copy a slice of nodes.func cloneNodes( []*html.Node) []*html.Node { := make([]*html.Node, 0, len())for , := range { = append(, cloneNode()) }return}// Deep copy a node. The new node has clones of all the original node's// children but none of its parents or siblings.func cloneNode( *html.Node) *html.Node { := &html.Node{Type: .Type,DataAtom: .DataAtom,Data: .Data,Attr: make([]html.Attribute, len(.Attr)), }copy(.Attr, .Attr)for := .FirstChild; != nil; = .NextSibling { .AppendChild(()) }return}func ( *Selection) ( []*html.Node, bool,func( *html.Node, *html.Node)) *Selection { := .Size() - 1// net.Html doesn't provide document fragments for insertion, so to get // things in the correct order with After() and Prepend(), the callback // needs to be called on the reverse of the nodes.if {for , := 0, len()-1; < ; , = +1, -1 { [], [] = [], [] } }for , := range .Nodes {for , := range {if != { (, cloneNode()) } else {if .Parent != nil { .Parent.RemoveChild() } (, ) } } }return}// eachNodeHtml parses the given html string and inserts the resulting nodes in the dom with the mergeFn.// The parsed nodes are inserted for each element of the selection.// isParent can be used to indicate that the elements of the selection should be treated as the parent for the parsed html.// A cache is used to avoid parsing the html multiple times should the elements of the selection result in the same context.func ( *Selection) ( string, bool, func( *html.Node, []*html.Node)) *Selection {// cache to avoid parsing the html for the same context multiple times := make(map[string][]*html.Node)var *html.Nodefor , := range .Nodes {if { = .Parent } else {if .Type != html.ElementNode {continue } = }if != nil { , := [nodeName()]if ! { = parseHtmlWithContext(, ) [nodeName()] = } (, cloneNodes()) } }return}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.